package com.buho29.rcmanager.widget;

import com.buho29.rcmanager.utils.Format;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

public class Chrono extends TextView {
    private static final String TAG = "ChronoView";
    
    public static final int STATE_PAUSE = 1;
    public static final int STATE_START = 2;
    public static final int STATE_STOP = 3;
    private static final int STATE_BACKGROUND = 4;
    private static final int STATE_NULL = 5;

    private long mBase;
	private long mPauseTime;
    private long mElapsedTime;
	private long mDelay = 100;
	private int mState = STATE_STOP;

    public int getState() {
		return mState;
	}


	private int backgroundState =STATE_STOP;
    
    private static final int TICK_WHAT = 2;
    /**
     * Initialize this Chronometer object.
     * Sets the base to the current time.
     */
    public Chrono(Context context) {
        this(context, null, 0);
    }

    /**
     * Initialize with standard view layout information.
     * Sets the base to the current time.
     */
    public Chrono(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * Initialize with standard view layout information and style.
     * Sets the base to the current time.
     */
    public Chrono(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        reset();
    }
 

    /**
     * Return the base time as set through {@link #setBase}.
     */
    public long getBase() {
        return mBase;
    }

    public void start() {
    	mState = STATE_START;
        updateRunning();
    }
    
    public void start(int msg) {
    	mCurrentState = STATE_PAUSE ;
        mState = STATE_START;
    	mPauseTime = msg;
        updateRunning();
    }
  
    public void pause() {
        mState = STATE_PAUSE;
        updateRunning();
    }
    
    public void pause(int msg) {
    	mState = mCurrentState = STATE_PAUSE ;
    	mPauseTime = msg;
    	setBase(SystemClock.elapsedRealtime()- mPauseTime);
    }
    
    public void stop() {
        mState = STATE_STOP;
        updateRunning();
    }
    
    public int getElapsedTime() {
        return (int) mElapsedTime;
    }

    public void reset() {
        mBase = SystemClock.elapsedRealtime();
        updateText(mBase);
        stop();
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.d(TAG, "onDetachedFromWindow");
        stop();
    }
    

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        Boolean visible = visibility == VISIBLE;
        if(!visible){
        	if(mState != STATE_BACKGROUND){
        		backgroundState = mState;
        		mState = STATE_BACKGROUND;
        	}
        	mHandler.removeMessages(TICK_WHAT);
        } else {
        	 updateRunning();
        }
        Log.d(TAG, "onWindowVisibilityChanged");
    }


    private int mCurrentState;
    
    private void updateRunning() {
    	
        if (mState != mCurrentState){
        	
        	switch (mState) {
			case STATE_STOP:
				mHandler.removeMessages(TICK_WHAT);
	            mPauseTime = 0;
				Log.d(TAG,"Stoped");
				break;
			case STATE_PAUSE:
				mHandler.removeMessages(TICK_WHAT);
				mPauseTime =  mElapsedTime;
				Log.d(TAG,"paused");
				break;
			case STATE_START:
				if(mCurrentState == STATE_STOP){
					setBase(SystemClock.elapsedRealtime());
					Log.d(TAG, "startstop");
				} else if(mCurrentState == STATE_PAUSE){
					setBase(SystemClock.elapsedRealtime()- mPauseTime);
					Log.d(TAG,"startpaused");
				}else {
					Log.d(TAG,"Start?");
					updateText(SystemClock.elapsedRealtime()- mPauseTime);
				}
				
				dispatchChronoViewTick();
				mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), mDelay);
				mPauseTime = 0;
				break;
			case STATE_BACKGROUND:
				if(backgroundState == STATE_START){
					mState = backgroundState;
					backgroundState = STATE_NULL;
					mCurrentState = STATE_NULL;
					updateRunning();
				}
				break;
        	}
        	
        	mCurrentState = mState;
        }
        
    }
    
    public void setBase(long base) {
        mBase = base;
        updateText(SystemClock.elapsedRealtime());
        dispatchChronoViewTick();
    }
    
    private synchronized void updateText(long now) {
        mElapsedTime = now - mBase;
        Log.d(TAG,"updateText"+String.valueOf(mElapsedTime/1000));
        setText(Format.formatDecisecondsToString((int)mElapsedTime/100));
    }
    
    private Handler mHandler = new Handler() {
        public void handleMessage(Message m) {
            if (mState == STATE_START) {
                updateText(SystemClock.elapsedRealtime());
                dispatchChronoViewTick();
                sendMessageDelayed(Message.obtain(this, TICK_WHAT), mDelay);
            //Log.d(TAG, "STATE_START");
            }//else Log.e(TAG,"STATE_START" );
        }
    };
	
	/////////////////////////////////////////////////////////////////
	//					Event
    //Tick
    public interface OnChronoViewTickListener {
        void onChronoViewTick(Chrono chronometer);
    }


    private OnChronoViewTickListener mOnChronoViewTickListener;
	/**
     * Sets the listener to be called when the chronometer changes.
     * 
     * @param listener The listener.
     */
    public void setOnChronoViewTickListener(OnChronoViewTickListener listener) {
        mOnChronoViewTickListener = listener;
    }

    /**
     * @return The listener (may be null) that is listening for chronometer change
     *         events.
     */
    public OnChronoViewTickListener getOnChronoViewTickListener() {
        return mOnChronoViewTickListener;
    }
    

    void dispatchChronoViewTick() {
        if (mOnChronoViewTickListener != null) {
            mOnChronoViewTickListener.onChronoViewTick(this);
        }
    }
}

